﻿/*
 * Copyright (c) 2009, Thiago M. Sayao <thiago.sayao@gmail.com>
 * All rights reserved.
 * 
 * Redistribution and use in source and binary forms, with or without 
 * modification, are permitted provided that the following conditions are met:
 *  * Redistributions of source code must retain the above copyright notice, 
 *    this list of conditions and the following disclaimer.
 *  * Redistributions in binary form must reproduce the above copyright notice,
 *    this list of conditions and the following disclaimer in the documentation
 *    and/or other materials provided with the distribution.
 *  * Neither the name of the author nor the names of its contributors may be 
 *    used to endorse or promote products derived from this software without 
 *    specific prior written permission.
 * 
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
 * POSSIBILITY OF SUCH DAMAGE.
 */

using System;
using System.Web;
using System.Web.Mvc;
using System.Web.Mvc.Html;
using System.Web.Routing;
using System.Web.Caching;
using System.Text;
using DotNetBurner.Web;
using DotNetBurner.Core;
using Resources;

namespace DotNetBurner
{
    public static class HtmlHelperExtensionsStoryList
    {
        /*
         * This is "hand-coded" for performance and caching reasons.
         */
        public static string StoryList(this HtmlHelper helper, BaseStoryListData model)
        {
            string key = String.Concat("storylistfor-", helper.ViewContext.HttpContext.Request.Url.PathAndQuery);
            string html;

            //this is not cached if user is not anonymous
            if (!model.IsAuthenticated && Cache.TryGet(key, out html))
                return html;

            UrlHelper urlHelper = new UrlHelper(helper.ViewContext.RequestContext);

            StringBuilder str = new StringBuilder();

            str.Append("<table class=\"story\" cellspacing=\"0\" cellpadding=\"0\">");
            str.Append("<tbody>");
    
            int count = 0;

            foreach(var story in model.Stories)
            {

                var detailAction = urlHelper.RouteUrl("Detail",
                                                      new RouteValueDictionary
                                                          {
                                                              {"id", story.StoryId},
                                                              {"title", story.Title.ConvertToUrlPath()}
                                                          });


                var categoryLink = helper.RouteLink(story.CategoryName, "Category",
                                                    new RouteValueDictionary
                                                        {
                                                            {"id", story.CategoryId},
                                                            {"name", story.CategoryName.ConvertToUrlPath()},
                                                            {"page", 1}
                                                        });

                var postedByAction = urlHelper.RouteUrl("PostedBy",
                                                        new RouteValueDictionary
                                                            {
                                                                {"id", story.PostedByUser.UserId},
                                                                {"name", story.PostedByUser.Name.ConvertToUrlPath()},
                                                                {"page", 1}
                                                            });

                string voteCountId = String.Concat("voteCount", story.StoryId);

                str.AppendFormat("<tr id=\"tr-for-{0}\">", story.StoryId);

                //Vote
                //this part cannot be cached (varies on user)
                str.Append("<td class=\"vote\">");
                str.AppendFormat("<div class=\"count\" onclick=\"window.open('{0}', '_self')\">", detailAction);
                str.AppendFormat("<div id=\"{0}\">{1}</div>", voteCountId, helper.GetVoteImages(story.VoteCount));
                str.AppendFormat("<div class=\"text\">{0}</div>", (story.VoteCount <= 1) ? Strings.OneVote : Strings.Votes);
                str.Append("</div>");
                str.Append(helper.StoryVoteLink(story.HasVoted, story.StoryId, story.VoteCount));
                str.Append("</td>");

                //Content
                str.Append("<td class=\"content\">");

                //Title
                str.Append("<div class=\"title\">");
                str.AppendFormat("<h2><a href=\"{0}\" onclick=\"javascript:Story.click({1});\" target=\"_blank\" title=\"{2}\">{3}</a></h2>",
                                 story.Url.AttributeEncode(), 
                                 story.StoryId, 
                                 story.Url.AttributeEncode(), 
                                 story.Title.HtmlEncode());

                str.Append("</div>");

                //Thumbnail
                if (PageGlimpseSettings.Settings.Enabled)
                {
                    str.Append("<div class=\"thumbnail\">");
                    str.Append(helper.Thumbnail(story));
                    str.Append("</div>");
                }

                //Description
                string domainUrl = story.Url.ExtractDomainNameFromURL();

                str.Append("<div class=\"description\">");
                str.Append("<p>");
                str.AppendFormat("<span class=\"link\"><a href=\"{0}\" target=\"_blank\" title=\"{1}\">{1}</a></span> - ",
                                 story.Url.ExtractSiteFromURL(),
                                 domainUrl);
                str.AppendFormat("<a href=\"{0}\" title=\"{1}\" class=\"body\">{2}</a>",
                                 detailAction,
                                 Strings.More,
                                 story.Description.WrapAt(StorySettings.Settings.StrippedDescLength).HtmlEncode());
                str.AppendFormat("&nbsp;<a href=\"{0}\" title=\"{1}\">{1}</a>", detailAction, Strings.More);
                str.Append("</p>");
                str.Append("</div>");

                //Summary
                string commentText = (story.CommentCount == 0) ? Strings.AddAComment : story.CommentCount + ((story.CommentCount == 1) ? " " + Strings.LComment : " " + Strings.LComments);

                str.Append("<div class=\"summary\">");
                //add comment
                str.AppendFormat("<a href=\"{0}#comments\" class=\"add-comment\">{1}</a>", detailAction, commentText);
                str.AppendFormat("<span class=\"category\">{0}</span>", categoryLink);
                if (!story.IsPublished && model.IsUserAdmOrModerator)
                {
                    str.AppendFormat("<span class=\"publish\"><a href=\"javascript:void(0)\" onclick=\"publish({0})\">{1}</a></span>", story.StoryId, Strings.Publish);
                }

                //posted by
                str.Append("<span class=\"postedby\">");
                string postedby = String.Concat(helper.Gravatar(story.PostedByUser.Email, 16), story.PostedByUser.Name.HtmlEncode());
                str.AppendFormat("<span class=\"person\"><a href=\"{0}\">{1}</a></span>&nbsp;", postedByAction, postedby);
                str.Append((story.IsPublished) ? Strings.MadePopular : Strings.Submitted);
                str.AppendFormat("&nbsp;<span class=\"ago\">{0} {1}.</span>",
                                 (story.IsPublished) ? story.PublishedAgo : story.PostedAgo, Strings.ago);
                str.Append("</span>");

                //End summary
                str.Append("</div>");

                //Tags
                str.Append("<span class=\"tags\">");
                str.Append(String.Concat(Strings.Tags.ToLower(), ":"));
                str.Append(helper.StoryTagsLinks(story.Tags));
                str.Append("</span>");

                str.Append("</td>");
                str.Append("</tr>");

                count++;
            }

            str.Append("</tbody>");
            str.Append("</table>");

            //Add the pager at the end
            str.Append(helper.Pager(model));

            html = str.ToString();

            if (!model.IsAuthenticated)
                Cache.CacheData(key, "StoryList", html);

            return html;
        }

        public static Cache Cache
        {
            get
            {
                return HttpRuntime.Cache;
            }
        }
    }
}
